#include "stdafx.h"
#include "base/thread/MessageLoopProxy.h"

namespace xBase
{
    CxMessageLoopProxy::CxMessageLoopProxy(CxMessageLoop* pTargetMsgLoop)
        :m_pTargetMsgLoop(pTargetMsgLoop)
    {
    }

    CxMessageLoopProxy::~CxMessageLoopProxy()
    {
    }

    VOID CxMessageLoopProxy::WillDestroyCurrentMessageLoop()
    {
        CxAutoLock lock(m_msgLoopLock);
        m_pTargetMsgLoop = NULL;
    }

    VOID CxMessageLoopProxy::PostTask_Helper(CTask* pTask, INT64 nDelayMilliSecond, BOOL bNestable)
    {
        CxAutoLock lock(m_msgLoopLock);

        if (m_pTargetMsgLoop && pTask)
        {
            m_pTargetMsgLoop->PostTask_Helper(pTask, nDelayMilliSecond, bNestable);
        }
        else if(pTask)
        {
            pTask->Destroy();
            pTask = NULL;
        }
    }

    VOID CxMessageLoopProxy::PostTask(CTask* pTask)
    {
        PostTask_Helper(pTask, 0, TRUE);
    }

    VOID CxMessageLoopProxy::PostDelayedTask(CTask* pTask, INT64 nDelayMilliSecond)
    {
        PostTask_Helper(pTask, nDelayMilliSecond, TRUE);
    }

    VOID CxMessageLoopProxy::PostNonNestableTask(CTask* pTask)
    {
        PostTask_Helper(pTask, 0, FALSE);
    }

    VOID CxMessageLoopProxy::PostNonNestableDelayedTask(CTask* pTask, INT64 nDelayMilliSecond)
    {
        PostTask_Helper(pTask, nDelayMilliSecond, FALSE);
    }

    BOOL CxMessageLoopProxy::RunNestMessageLoop()
    {
        if (!m_pTargetMsgLoop)
        {
            return FALSE;
        }

        BOOL bOldState = m_pTargetMsgLoop->NestableTasksAllowed();
        m_pTargetMsgLoop->SetNestableTasksAllowed(TRUE);
        m_pTargetMsgLoop->Run();
        m_pTargetMsgLoop->SetNestableTasksAllowed(bOldState);

        return TRUE;
    }

    VOID CxMessageLoopProxy::SetRunNestMessageLoopAllowed(BOOL bAllowed)
    {
        if (!m_pTargetMsgLoop)
        {
            return;
        }
        else
        {
            m_pTargetMsgLoop->SetNestableTasksAllowed(bAllowed);
        }
    }

    BOOL CxMessageLoopProxy::IsRunNestMessageLoopAllowed()
    {
        if (!m_pTargetMsgLoop)
        {
            return FALSE;
        }
        else
        {
            return m_pTargetMsgLoop->NestableTasksAllowed();
        }
    }

    INT CxMessageLoopProxy::RunDepth()
    {
        if (!m_pTargetMsgLoop)
        {
            return FALSE;
        }

        return m_pTargetMsgLoop->RunDepth();
    }

    VOID CxMessageLoopProxy::Quit()
    {
        CxAutoLock lock(m_msgLoopLock);
        if (m_pTargetMsgLoop)
        {
            m_pTargetMsgLoop->Quit();
        }
    }

    VOID CxMessageLoopProxy::QuitNow()
    {
        CxAutoLock lock(m_msgLoopLock);
        if (m_pTargetMsgLoop)
        {
            m_pTargetMsgLoop->QuitNow();
        }
    }
}